//#ifndef LiquidCrystal_h
//#define LiquidCrystal_h

//#include <inttypes.h>
//#include "Print.h"

//#include <SPI.h>

//// commands
//#define LCD_CLEARDISPLAY 0x01
//#define LCD_RETURNHOME 0x02
//#define LCD_ENTRYMODESET 0x04
//#define LCD_DISPLAYCONTROL 0x08
//#define LCD_CURSORSHIFT 0x10
//#define LCD_FUNCTIONSET 0x20
//#define LCD_SETCGRAMADDR 0x40
//#define LCD_SETDDRAMADDR 0x80

//// flags for display entry mode
//#define LCD_ENTRYRIGHT 0x00
//#define LCD_ENTRYLEFT 0x02
//#define LCD_ENTRYSHIFTINCREMENT 0x01
//#define LCD_ENTRYSHIFTDECREMENT 0x00

//// flags for display on/off control
//#define LCD_DISPLAYON 0x04
//#define LCD_DISPLAYOFF 0x00
//#define LCD_CURSORON 0x02
//#define LCD_CURSOROFF 0x00
//#define LCD_BLINKON 0x01
//#define LCD_BLINKOFF 0x00

//// flags for display/cursor shift
//#define LCD_DISPLAYMOVE 0x08
//#define LCD_CURSORMOVE 0x00
//#define LCD_MOVERIGHT 0x04
//#define LCD_MOVELEFT 0x00

//// flags for function set
//#define LCD_8BITMODE 0x10
//#define LCD_4BITMODE 0x00
//#define LCD_2LINE 0x08
//#define LCD_1LINE 0x00
//#define LCD_5x10DOTS 0x04
//#define LCD_5x8DOTS 0x00

//class LiquidCrystal : public Print {
//public:
//  LiquidCrystal(uint8_t rs, uint8_t enable,
//		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
//		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
//  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
//		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
//		uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
//  LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable,
//		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
//  LiquidCrystal(uint8_t rs, uint8_t enable,
//		uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3);
//  LiquidCrystal(uint8_t ssPin); //SPI to ShiftRegister 74HC595 ##########

//  void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable,
//	    uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
//	    uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7);
//		
//  void initSPI(uint8_t _ssPin); //SPI ##################################
//    
//  void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS);

//  void clear();
//  void home();

//  void noDisplay();
//  void display();
//  void noBlink();
//  void blink();
//  void noCursor();
//  void cursor();
//  void scrollDisplayLeft();
//  void scrollDisplayRight();
//  void leftToRight();
//  void rightToLeft();
//  void autoscroll();
//  void noAutoscroll();

//  void createChar(uint8_t, uint8_t[]);
//  void setCursor(uint8_t, uint8_t); 
//  virtual size_t write(uint8_t);
//  void command(uint8_t);
//private:
//  void send(uint8_t, uint8_t);
//  void spiSendOut();      // SPI ###########################################
//  void write4bits(uint8_t);
//  void write8bits(uint8_t);
//  void pulseEnable();
//  
//  
//  uint8_t _rs_pin; // LOW: command.  HIGH: character.
//  uint8_t _rw_pin; // LOW: write to LCD.  HIGH: read from LCD.
//  uint8_t _enable_pin; // activated by a HIGH pulse.
//  uint8_t _data_pins[8];
//  
//  //SPI #####################################################################
//  uint8_t _bitString; //for SPI  bit0=not used, bit1=RS, bit2=RW, bit3=Enable, bits4-7 = DB4-7
//     bool _usingSpi;  //to let send and write functions know we are using SPI 
//  uint8_t _latchPin;
//  uint8_t _clockDivider;
//  uint8_t _dataMode;
//  uint8_t _bitOrder;//SPI ####################################################
//  
//  uint8_t _displayfunction;
//  uint8_t _displaycontrol;
//  uint8_t _displaymode;

//  uint8_t _initialized;

//  uint8_t _numlines,_currline;
//};

//#endif

//#include "main.h"
#include "stm32f0xx_conf.h"
uint32_t TickValue=0;

#define RS GPIO_Pin_13 // RS is named as Port 13
#define RW GPIO_Pin_14 // RW is named as Port 14
#define EN GPIO_Pin_15 // EN is named as Port 15

//------------------------------------------------------------------------------
// Function Name : delay_ms
// Description : delay for some time in ms unit(accurate)
// Input : n_ms is how many ms of time to delay
//------------------------------------------------------------------------------
void TimingDelay_Decrement(void)
{
TickValue--; 
}

void delay_ms(uint32_t n_ms)
{
SysTick_Config(8000*PLL_MUL_X - 30);
TickValue = n_ms;
while(TickValue == n_ms)
; 
SysTick_Config(8000*PLL_MUL_X);
while(TickValue != 0)
;
}
//------------------------------------------------------------------------------
// Function Name : Init GPIO 
// Description : pins ,port clock & mode initialization.
//------------------------------------------------------------------------------
void initgpio()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOC, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_Init(GPIOA, &GPIO_InitStructure);


}
//------------------------------------------------------------------------------
// Function Name : s_init
// Description : Send Instruction Function (RS=0 & RW=0)
//------------------------------------------------------------------------------

void s_init() 
{
GPIOC->BRR=RS;
GPIOC->BRR=RW;
}
//------------------------------------------------------------------------------
// Function Name : s_data
// Description : Send Data Select routine(RS=1 & RW=0)
//------------------------------------------------------------------------------

void s_data() 
{
GPIOC->BSRR=RS;
GPIOC->BRR=RW;
}
//------------------------------------------------------------------------------
// Function Name : s_latch
// Description : Latch Data/Instruction on LCD Databus.
//------------------------------------------------------------------------------

void s_latch() 
{
GPIOC->BSRR=EN;
delay_ms(10);
GPIOC->BRR=EN;
delay_ms(10);
}

/*******************************************************************************
* Function Name : main
* Description : Main program.
*******************************************************************************/
int main(void) //Main function
{ 

initgpio();

int k=0; 
char a[]="WWW.EEHERALD.COM";
char b[]="EMBEDDED SYSTEMS";

GPIOC->BRR=RS; //Initialize RS=0 for selecting instruction Send
GPIOC->BRR=RW; // Select RW=0 to write Instruction/data on LCD
GPIOC->BSRR=EN; // EN=1 for unlatch. (used at initial condition)

delay_ms(10);

s_init(); //Call Instruction Select routine
GPIOA->ODR=0x0001; // Clear Display, Cursor to Home 
s_latch(); //Latch the above instruction 
GPIOA->ODR=0x0038; // Display Function (2 rows for 8-bit data; small) 
s_latch(); //Latch this above instruction 4 times
s_latch(); 
s_latch(); 
s_latch(); 
GPIOA->ODR=0x000E; // Display and Cursor on, Cursor Blink off 
s_latch(); //Latch the above instruction 
GPIOA->ODR=0x0010; // Cursor shift left 
s_latch(); //Latch the above instruction 
GPIOA->ODR=0x0006; // Cursor Increment, Shift off 
s_data(); //Change the input type to Data.(before it was instruction input)
s_latch(); //Latch the above instruction

for(k=0;a[k];k++)
{
GPIOA->ODR=a[k]; //It will send a[0]='P' as = '0x0050' on Port A.
s_latch(); //Latch the above instruction only once. Or it will clone each character twice if you latch twice.
}
GPIOC->BRR=RS; //Initialize RS=0 for selecting instruction Send
GPIOC->BRR=RW; // Select RW=0 to write Instruction/data on LCD
GPIOC->BSRR=EN; // EN=1 for unlatch. (used at initial condition)

delay_ms(10);
GPIOA->ODR=0x00C0; // Move cursor to beginning of second row 
s_latch(); //Latch the above instruction
s_data(); //Change the input type to Data.(before it was instruction input)
for(k=0;b[k];k++)
{
GPIOA->ODR=b[k]; //It will send b[0]='E' as = '0x0044' on Port A.
s_latch();//Latch the above instruction only once. Or it will clone each character twice if you latch twice.
}
s_init(); 
}
